﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		LinqExtensions.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 //   File:            LinqExtensions.cs
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion
 
namespace System.Linq
{
	#region Usings

	using System.Collections;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;

	#endregion

	/// <summary>
	/// 	Adds behavior to System.Linq.
	/// </summary>
	public static class LinqExtensions
	{
		/// <summary>
		/// 	Eaches the specified enumeration.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "source">The enumeration.</param>
		/// <param name = "action">The action.</param>
		public static void ForEach< T > ( this IEnumerable<T> source , Action<T> action )
		{
			foreach ( T item in source )
				action ( item );
		}

		/// <summary>
		/// 	Toes the flat.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "source">The source.</param>
		/// <param name = "childPredicate">The child predicate.</param>
		/// <returns></returns>
		public static IEnumerable<T> ToFlat< T > ( this IEnumerable<T> source , Func<T , IEnumerable<T>> childPredicate )
		{
			foreach ( T t in source )
			{
				yield return t;
				IEnumerable<T> children = childPredicate ( t );
				if (children != null)
					foreach ( T child in ToFlat ( children , childPredicate ) )
						yield return child;
			}
		}

		/// <summary>
		/// 	Removes the duplicates from lists.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "source">The source.</param>
		/// <returns></returns>
		public static IEnumerable<T> RemoveDuplicatesFromLists< T > ( this IEnumerable source )
		{
			Dictionary<T , int> uniqueStore = new Dictionary<T , int> ();
			Collection<T> finalList = new Collection<T> ();

			foreach ( T currValue in source )
			{
				if ( uniqueStore.ContainsKey ( currValue ) )
					continue;

				uniqueStore.Add ( currValue , 0 );
				finalList.Add ( currValue );
			}
			return finalList;
		}

		/// <summary>
		/// 	Finds the specified source.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "source">The source.</param>
		/// <param name = "match">The match.</param>
		/// <returns></returns>
		public static T Find< T > ( this IEnumerable<T> source , Predicate<T> match )
		{
			foreach ( T item in source )
			{
				if ( match ( item ) )
					return item;
			}

			return default( T );
		}

		/// <summary>
		/// 	Adds the range.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "list">The list.</param>
		/// <param name = "elements">The elements.</param>
		public static void AddRange< T > ( this ICollection<T> list , IEnumerable<T> elements )
		{
			foreach ( T e in elements )
				list.Add ( e );
		}
	}
}
